package com.ttg.web.service.job.primitive.impl;

import com.google.common.collect.Lists;
import com.google.common.util.concurrent.ListenableFuture;
import com.ttg.common.annotation.TaskRunMethod;
import com.ttg.common.dto.PrimitiveBaseDTO;
import com.ttg.common.utils.LongUtil;
import com.ttg.common.vo.TaskResultVO;
import com.ttg.model.pojo.BankAccountPrimitive;
import com.ttg.model.pojo.BankPublicMerchTradePrimitive;
import com.ttg.model.vo.MerchAcctInfoVO;
import com.ttg.model.vo.MerchTradePrimitiveTaskVO;
import com.ttg.model.vo.SettAcctTimeAmtVO;
import com.ttg.web.dao.BankAccountPrimitiveDao;
import com.ttg.web.dao.BankPublicMerchTradePrimitiveDao;
import com.ttg.web.juc.TasktemplateHelper;
import com.ttg.web.service.job.JobCommon;
import com.ttg.web.service.job.primitive.MerchTradePrimitiveService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * Description：
 * Author: chenyou
 * Date: 2025/11/11 11:17
 * Company: ttg
 * Copyright: Copyright (c) 2025
 */
@Service
@TaskRunMethod(value = "saveMerchTradePrimitiveTask")
public class MerchTradePrimitiveServiceImpl extends JobCommon implements MerchTradePrimitiveService {
    @Value("${tlinx.isJuc:false}")
    private volatile Boolean isJuc;//是否启用异步回调
    @Autowired
    private TasktemplateHelper tasktemplateHelper;

    @Autowired
    private BankPublicMerchTradePrimitiveDao tradePrimitiveDao;
    @Autowired
    private BankAccountPrimitiveDao accountPrimitiveDao;

    @Override
    public TaskResultVO saveMerchTradePrimitive(PrimitiveBaseDTO reqDto) {
        Integer day = Integer.parseInt(reqDto.getDate());
        //每日定时从晋享e付获取商户原始数据
        //todo sftp拉取过程
        List<BankPublicMerchTradePrimitive> primitives = JobCommon.testMerchPrimitives(day);


        //删除指定日期旧数据
        tradePrimitiveDao.deleteByDay(Integer.valueOf(day));
        //通过会员id关联账户原始数据表和商户交易原始数据表,补全商户结算账户每日时点余额
        //拆分,按批次执行
        List<ListenableFuture<TaskResultVO>> futures = new ArrayList<>();
        List<TaskResultVO> results = new ArrayList<>();
        List<List<BankPublicMerchTradePrimitive>> partLists = Lists.partition(primitives,500);
        for(List<BankPublicMerchTradePrimitive> part:partLists){
            MerchTradePrimitiveTaskVO vo = new MerchTradePrimitiveTaskVO();
            vo.setDay(day);
            vo.setPart(part);
            if(isJuc){
                futures.add(tasktemplateHelper.submit(this,vo));
            }else {
                TaskResultVO result = saveMerchTradePrimitiveTask(vo);
                results.add(result);
            }
        }

        return taskResult(results,futures,isJuc);
    }

    public TaskResultVO saveMerchTradePrimitiveTask(MerchTradePrimitiveTaskVO taskVo){
        Integer day = taskVo.getDay();
        List<BankPublicMerchTradePrimitive> part = taskVo.getPart();

        List<String> mctNos = part.stream().map(o -> o.getMctNo()).collect(Collectors.toList());

        List<MerchAcctInfoVO> mctAcctInfoVoList = tradePrimitiveDao.getAcctInfoByMctNos(day,mctNos);
        List<Long> acctNos = mctAcctInfoVoList.stream().map(o -> o.getActNo()).distinct().collect(Collectors.toList());
        if(!CollectionUtils.isEmpty(acctNos)){
            List<SettAcctTimeAmtVO> settAcctTimeAmtVOS = accountPrimitiveDao.getSettAcctTimeAmt(day,acctNos);
            for(SettAcctTimeAmtVO vo:settAcctTimeAmtVOS){
                Optional<MerchAcctInfoVO> optional = mctAcctInfoVoList.stream().filter(o -> LongUtil.equals(vo.getActNo(),o.getActNo())).findFirst();
                if(optional.isPresent()){
                    MerchAcctInfoVO merchAcctInfoVO = optional.get();
                    vo.setMctNo(merchAcctInfoVO.getMctNo());
                }
            }

            Map<String,List<SettAcctTimeAmtVO>> mctMap = settAcctTimeAmtVOS.stream().collect(Collectors.groupingBy(o -> o.getMctNo()));
            for(BankPublicMerchTradePrimitive merchTradePrimitive:part){
                List<SettAcctTimeAmtVO> settAcctTimeAmtVOS1 = mctMap.get(merchTradePrimitive.getMctNo());
                if(!CollectionUtils.isEmpty(settAcctTimeAmtVOS1)) {
                    Long sumTimeAmt = settAcctTimeAmtVOS1.stream().mapToLong(o -> o.getTimeAmt().longValue()).sum();
                    merchTradePrimitive.setTimeAmt(new BigDecimal(sumTimeAmt));
                }
            }
        }

        //保存
        tradePrimitiveDao.saveBatch(part);
        return taskReuslt(JobCommon.Status.SUCCESS.getValue(),false,"ok");
    }
}
